package queue

type RingQueue struct {
	elements []interface{}
	head     int
	tail     int
	cap      int
}

func NewRingQueue(cap int) *RingQueue {
	return &RingQueue{
		elements: make([]interface{}, cap+1),
		head:     0,
		tail:     0,
		cap:      cap + 1,
	}
}

func (r *RingQueue) Empty() bool {
	return r.head == r.tail
}

func (r *RingQueue) Full() bool {
	return (r.tail+1)%r.cap == r.head
}

func (r *RingQueue) Push(value interface{}) bool {
	if r.Full() {
		return false
	}
	r.elements[r.tail] = value
	r.tail = (r.tail + 1) % r.cap
	return true
}

func (r *RingQueue) Pop() (interface{}, bool) {
	if r.Empty() {
		return nil, false
	}
	value := r.elements[r.head]
	r.head = (r.head + 1) % r.cap
	return value, true
}
